package com.ccys.app.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.ccys.app.service.DeliveryAddressInfoService;
import com.ccys.common.vo.ResponseResultApp;
import com.ccys.db.cache.UserUtil;
import com.ccys.db.dto.app.updateAddressScreen.DeleteDeliveryAddressDto;
import com.ccys.db.dto.app.updateAddressScreen.UpdateDeliveryAddressInfoDto;
import com.ccys.db.entity.TblDeliveryCountryLocation;
import com.ccys.db.entity.TblMember;
import com.ccys.db.entity.TblMemberDeliveryAddress;
import com.ccys.db.mapper.TblDeliveryCountryLocationMapper;
import com.ccys.db.mapper.TblMemberDeliveryAddressMapper;
import com.ccys.db.vo.app.updateAddressScreen.UpdateDeliveryAddressInfoVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.math.BigDecimal;

/**
 * @program: WhiteCoat
 * @description: 快递信息详情接口
 * @author: ZhangJingCan
 * @create: 2024-01-30 13:12
 **/

@Service
public class DeliveryAddressInfoServiceImpl implements DeliveryAddressInfoService {

    /**
     * 用户快递地址表
     */
    @Resource
    private TblMemberDeliveryAddressMapper tblMemberDeliveryAddressMapper;

    @Resource
    private TblDeliveryCountryLocationMapper tblDeliveryCountryLocationMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResultApp<UpdateDeliveryAddressInfoVo> updateDeliveryAddressInfo(UpdateDeliveryAddressInfoDto dto) {
        //校验是否登录
        TblMember member = UserUtil.getCurLoginMember();
        if (ObjectUtil.isEmpty(member)) {
            return ResponseResultApp.error(401, "Request require authorization.");
        }
        //检查address字段 - 对方postman允许传入空 - 但是页面显示必须填写
        if (ObjectUtil.isEmpty(dto.getAddress())) {
            return ResponseResultApp.error(400, "Address is mandatory");
        }

        //校验地址id是否存在
        if (ObjectUtil.isEmpty(dto.getId())) {
            return ResponseResultApp.error(400, "The address could not be found.");
        }

        //如果未传入国家ID - 设置默认为新加坡 = 203
        if (ObjectUtil.isEmpty(dto.getCountry_id())) {
            dto.setCountry_id("203");
        }

        //校验邮政编码 - < 4 || > 10位数则抛出异常
        if (ObjectUtil.isEmpty(dto.getPostal_code()) || dto.getPostal_code().length() < 4 || dto.getPostal_code().length() > 10) {
            return ResponseResultApp.error(447, "Invalid postal code");
        }

        //校验经纬度
        if (ObjectUtil.isEmpty(dto.getLatitude()) || ObjectUtil.isEmpty(dto.getLongitude())) {
            return ResponseResultApp.error(400, "illegal request");
        }
        // 检查latitude的范围是否超出 [-90, 90]
        // 对方的校验为：model.latitude > 90 || model.latitude < -90
        if (dto.getLatitude().compareTo(new BigDecimal("90")) > 0 || dto.getLatitude().compareTo(new BigDecimal("-90")) < 0) {
            return ResponseResultApp.error(400, "Latitude invalid");
        }

        // 检查longitude的范围是否超出 [-180, 180]
        // 对方的校验为model.longitude > 180 || model.longitude < -180
        if (dto.getLongitude().compareTo(new BigDecimal("180")) > 0 || dto.getLongitude().compareTo(new BigDecimal("-180")) < 0) {
            return ResponseResultApp.error(400, "Longitude invalid");
        }

        //检查详情字段如果为空则设置为一个空字符串
        if (ObjectUtil.isNull(dto.getDetail_address())) {
            dto.setDetail_address("");
        }

        //查询数据 - 检查是否存在
        Example example = new Example(TblMemberDeliveryAddress.class);
        example.createCriteria()
                .andEqualTo("id", dto.getId())
                .andEqualTo("memId", member.getId())
                .andEqualTo("delFlag", 0);
        TblMemberDeliveryAddress address = tblMemberDeliveryAddressMapper.selectOneByExample(example);
        //如果查询出的数据为空 - 返回异常
        if (ObjectUtil.isEmpty(address)) {
            return ResponseResultApp.error(400, "The address was not found");
        }

        //值转换 - 对方传入的是true或者false或者null
        if (ObjectUtil.isNotEmpty(dto.getIs_default())) {
            //是否为默认地址
            address.setIsDefault(dto.getIs_default() ? 1 : 0);
            //如果为true - 则将其余所有地址设置为0 - 1为默认
            if (dto.getIs_default()) {
                tblMemberDeliveryAddressMapper.updateDefaultByAddressAndByMemberId(address.getId(), member.getId());
            }
        }


        /**
         * 对方检查是否有存在同名数据的条件 - 存在则抛出异常
         * IF EXISTS ( SELECT  1
         *                             FROM    dbo.tbl_Member_Delivery_Address
         *                             WHERE   mem_id = @prm_mem_id
         *                                     AND mem_delivery_address_id <> @prm_mem_delivery_address_id
         *                                     AND mem_delivery_address = @prm_mem_delivery_address
         * 									AND mem_delivert_floor_number=@prm_mem_delivery_floor_number
         * 									AND mem_delivery_postal_code = @prm_mem_delivery_postal_code
         * 									AND country_id = @prm_country_id
         * 									AND tier_1 = @prm_tier_1
         * 									AND tier_2 = @prm_tier_2
         * 									AND tier_3 = @prm_tier_3
         * 							)
         *                 BEGIN
         *                     SELECT  -3 AS result -- mem_delivery_address is exist
         *
         *  如果存在抛出的异常为：400  "The address you are trying to add is already in your address book."
         */
        Example checkData = new Example(TblMemberDeliveryAddress.class);
        checkData.createCriteria()
                .andEqualTo("memId", member.getId())
                .andEqualTo("address", dto.getAddress())
                .andEqualTo("countryId", dto.getCountry_id())
                .andEqualTo("postalCode", dto.getPostal_code())
                .andNotEqualTo("id", dto.getId())
                .andEqualTo("delFlag", 0);
        if (ObjectUtil.isNotNull(dto.getFloor_number())) {
            //楼层号
            checkData.createCriteria().andEqualTo("floorNumber", dto.getFloor_number());
            //设置需要修改进数据库的数据
            address.setFloorNumber(dto.getFloor_number());
        }
        if (ObjectUtil.isNotNull(dto.getTier_1())) {
            checkData.createCriteria().andEqualTo("tier1", dto.getTier_1());
            //设置需要修改进数据库的数据
            address.setTier1(dto.getTier_1());
        }
        if (ObjectUtil.isNotNull(dto.getTier_2())) {
            checkData.createCriteria().andEqualTo("tier2", dto.getTier_2());
            //设置需要修改进数据库的数据
            address.setTier2(dto.getTier_2());
        }
        if (ObjectUtil.isNotNull(dto.getTier_3())) {
            checkData.createCriteria().andEqualTo("tier3", dto.getTier_3());
            //设置需要修改进数据库的数据
            address.setTier3(dto.getTier_3());
        }
        //查询 - 检查是否存在相等条件的数据
        TblMemberDeliveryAddress check = tblMemberDeliveryAddressMapper.selectOneByExample(checkData);
        if (ObjectUtil.isNotEmpty(check)) {
            return ResponseResultApp.error(400, "The address you are trying to add is already in your address book.");
        }

        //设置经纬度
        address.setLatitude(dto.getLatitude());
        address.setLongitude(dto.getLongitude());
        address.setCountryId(dto.getCountry_id());
        address.setState(dto.getState() != null ? dto.getState() : address.getState());
        address.setInstructions(dto.getDelivery_instructions() != null ? dto.getDelivery_instructions() : address.getInstructions());
        //修改进数据库
        tblMemberDeliveryAddressMapper.updateByPrimaryKeySelective(address);

        //准备返回数据
        UpdateDeliveryAddressInfoVo vo = new UpdateDeliveryAddressInfoVo();
        vo.setId(address.getId());
        vo.setMemDeliveryAddressId(address.getId());
        vo.setPostalCode(address.getPostalCode());
        vo.setAddress(address.getAddress());
        vo.setFloorNumber(address.getFloorNumber());
        vo.setLatitude(address.getLatitude());
        //查询是否可配送的数据
        if (ObjectUtil.isNotEmpty(address.getDclId())) {
            //查询 todo 不知道是不是一对一，但是看对方函数是一对一的感觉 先按照一对一查询 - 以及是否使用id还是dc_id？ - 这里取的id
            Example dclExample = new Example(TblDeliveryCountryLocation.class);
            dclExample.createCriteria()
                    .andEqualTo("id", address.getDclId())
                    .andEqualTo("dclStatus", 1)
                    .andEqualTo("delFlag", 0);
            TblDeliveryCountryLocation dcl = tblDeliveryCountryLocationMapper.selectOneByExample(dclExample);
            if (ObjectUtil.isNotEmpty(dcl)) {
                /**
                 * CASE
                 * WHEN country_id = @mem_country_of_residence and country_id = 245 and ISNULL(@DCL_can_deliver, 0) = 1 THEN 1 -- VietNam
                 * WHEN country_id = @mem_country_of_residence and country_id = 106 and ISNULL(mem_delivery_postal_code, '') != '' THEN 1 -- Indo
                 * When country_id = @mem_country_of_residence and country_id != 106 then 1
                 * WHEN country_id IS NULL THEN 1
                 * ELSE 0 END
                 */
                //设置是否可配送
                if (address.getCountryId().equals("245") && address.getCountryId().equals(member.getCurrentCountry()) && ObjectUtil.isNotEmpty(dcl.getDclCanDeliver()) && dcl.getDclCanDeliver() == 1) {
                    vo.setCanDeliver(1);
                } else if (address.getCountryId().equals("106") && address.getCountryId().equals(member.getCurrentCountry()) && ObjectUtil.isNotEmpty(address.getPostalCode())) {
                    vo.setCanDeliver(1);
                } else if (!address.getCountryId().equals("106") && address.getCountryId().equals(member.getCurrentCountry())) {
                    vo.setCanDeliver(1);
                }
            } else {
                vo.setCanDeliver(0);
            }
            //设置deliveryTimeText
            /**
             * CASE WHEN DCL.DCL_id IS NOT NULL
             * THEN CAST(DCL.DCL_min_value AS VARCHAR) + ' - ' + CAST(DCL.DCL_max_value AS VARCHAR) + ' ' + (CASE WHEN DCL_unit_type = 1 THEN dbo.fn_Get_Translation_Name('hours',@lang) WHEN DCL_unit_type = 2 THEN dbo.fn_Get_Translation_Name('days',@lang) ELSE '' END)
             * ELSE '' END AS delivery_time_text,
             */
            //todo
//            if (ObjectUtil.isNotEmpty(dcl.getId())){
//
//            }

        } else {
            vo.setCanDeliver(0);
        }
        vo.setTier1(address.getTier1() != null ? address.getTier1() : "");
        vo.setTier2(address.getTier2() != null ? address.getTier2() : "");
        vo.setTier3(address.getTier3() != null ? address.getTier3() : "");
        vo.setDeliveryInstructions(address.getInstructions() != null ? address.getInstructions() : "");
        //succ: 0  "Your address has been successfully updated."
        return ResponseResultApp.success("Your address has been successfully updated.", vo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResultApp deleteDeliveryAddress(DeleteDeliveryAddressDto dto) {
        //校验是否登录
        TblMember member = UserUtil.getCurLoginMember();
        if (ObjectUtil.isEmpty(member)) {
            return ResponseResultApp.error(401, "Request require authorization.");
        }

        //校验地址id是否存在
        if (ObjectUtil.isEmpty(dto.getId())) {
            return ResponseResultApp.error(400, "The id field is required.");
        }
        TblMemberDeliveryAddress address = tblMemberDeliveryAddressMapper.selectByPrimaryKey(dto.getId());
        //查询数据
        if (ObjectUtil.isEmpty(address)) {
            return ResponseResultApp.error(400, "The address could not be found.");
        }
        //修改数据设置为已删除
        address.setDelFlag(1);
        //修改进数据库
        tblMemberDeliveryAddressMapper.updateByPrimaryKeySelective(address);
        return ResponseResultApp.success("Your address has been successfully deleted.", null);
    }

}
